﻿using System;
using System.Net;
using System.Xml;
using System.IO;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyMedia
{
    public class YouTube
    {
        #region "VideoInfo"
        string LastSource;
        string userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.98 Safari/534.13";
        public string VideoURL;
        public string VideoTITLE;
        public string VideoIMG;
        public string VideoDESC;
        public string VideoVIEWS;
        public string VideoLIKES;
        public string VideoDISLIKES;
        public Bitmap Thumbnail;

        public bool Create(string url)
        {
            if (url != "")
            {
                if (!url.Contains("http://"))
                {
                    url = "http://"+url;
                }

                HttpWebRequest YoutubeRequest = (HttpWebRequest)HttpWebRequest.Create(url);
                YoutubeRequest.AllowAutoRedirect = true;
                YoutubeRequest.KeepAlive = false;
                YoutubeRequest.UserAgent = userAgent;
                YoutubeRequest.Method = "GET";
                HttpWebResponse myWebResponse = (HttpWebResponse)YoutubeRequest.GetResponse();
                if (myWebResponse.StatusCode == HttpStatusCode.OK)
                {
                    StreamReader myWebSource = new StreamReader(myWebResponse.GetResponseStream());
                    LastSource = myWebSource.ReadToEnd();
                    myWebResponse.Close();
                    VideoTITLE = GetStringInBetween("<meta name=\"title\" content=\"", "\">", LastSource, false, false).Replace("\\/", "/").Replace("%2C", ",");
                    VideoTITLE = System.Text.RegularExpressions.Regex.Replace(VideoTITLE, @"[^\w\.@\[\]\\/()&%' #{}€$£!=-]", String.Empty);
                    VideoURL = GetStringInBetween(",18|", ",5|", LastSource, false, false).Replace("\\u0026", "&").Replace("\\/", "/").Replace("%2C", ",") + "&title=" + VideoTITLE;
                    VideoIMG = GetStringInBetween("<meta property=\"og:image\" content=\"", "\">", LastSource, false, false);
                    VideoDESC = GetStringInBetween("<meta property=\"og:description\" content=\"", "\">", LastSource, false, false);
                    VideoVIEWS = GetStringInBetween("<span class=\"watch-view-count\"><strong>", "</strong></span>", LastSource, false, false);
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
                throw new Exception("Invalid YoutTube URL");
            }
        }
        public void GetThumbnail()
        {
            try
            {
                WebClient client = new WebClient();
                Stream stream = client.OpenRead(VideoIMG);
                Thumbnail = new Bitmap(stream);
                stream.Flush();
                stream.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
        private static string GetStringInBetween(string strBegin, string strEnd, string strSource, bool includeBegin, bool includeEnd)
        {
            string[] result = { string.Empty, string.Empty };
            int iIndexOfBegin = strSource.IndexOf(strBegin);

            if (iIndexOfBegin != -1)
            {
                // include the Begin string if desired 
                if (includeBegin)
                    iIndexOfBegin -= strBegin.Length;

                strSource = strSource.Substring(iIndexOfBegin + strBegin.Length);

                int iEnd = strSource.IndexOf(strEnd);
                if (iEnd != -1)
                {
                    // include the End string if desired 
                    if (includeEnd)
                        iEnd += strEnd.Length;
                    result[0] = strSource.Substring(0, iEnd);
                    // advance beyond this segment 
                    if (iEnd + strEnd.Length < strSource.Length)
                        result[1] = strSource.Substring(iEnd + strEnd.Length);
                }
            }
            else
                // stay where we are 
                result[1] = strSource;
            return result[0];
        }
        #endregion

        #region "VideoDownload"
        private BackgroundWorker DownloadWorker = new BackgroundWorker();
        private string URL2Download;
        private string Path2Save;
        public int VideoDownloadProgess;

        public void DownloadVideo(string VideoLink, string Directory2Save)
        {
            URL2Download = VideoLink;
            Path2Save = Directory2Save;
            DownloadWorker.WorkerReportsProgress = true;
            DownloadWorker.DoWork += new DoWorkEventHandler(DoDownload);
            DownloadWorker.ProgressChanged += new ProgressChangedEventHandler(DownloadWorker_ProgressChanged);
            DownloadWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DownloadWorker_RunWorkerCompleted);
            DownloadWorker.RunWorkerAsync();
        }
        public void DoDownload(object sender, DoWorkEventArgs e)
        {
                string sUrlToReadFileFrom = URL2Download;
                string sFilePathToWriteFileTo = Path2Save;

                Uri url = new Uri(sUrlToReadFileFrom);
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
                System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
                response.Close();
                Int64 iSize = response.ContentLength; //Bytes

                // keeps track of the total bytes downloaded so we can update the progress bar
                Int64 iRunningByteTotal = 0;

                // use the webclient object to download the file
                using (System.Net.WebClient client = new System.Net.WebClient())
                {
                    // open the file at the remote URL for reading
                    using (System.IO.Stream streamRemote = client.OpenRead(new Uri(sUrlToReadFileFrom)))
                    {
                        // using the FileStream object, we can write the downloaded bytes to the file system
                        using (Stream streamLocal = new FileStream(sFilePathToWriteFileTo, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            // loop the stream and get the file into the byte buffer
                            int iByteSize = 0;
                            byte[] byteBuffer = new byte[iSize];
                            while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
                            {
                                // write the bytes to the file system at the file path specified
                                streamLocal.Write(byteBuffer, 0, iByteSize);
                                iRunningByteTotal += iByteSize;

                                // calculate the progress out of a base "100"
                                double dIndex = (double)(iRunningByteTotal);
                                double dTotal = (double)byteBuffer.Length;
                                double dProgressPercentage = (dIndex / dTotal);
                                int iProgressPercentage = (int)(dProgressPercentage * 100);

                                // update the progress bar
                                DownloadWorker.ReportProgress(iProgressPercentage);
                            }

                            // clean up the file stream
                            streamLocal.Close();
                        }

                        // close the connection to the remote server
                        streamRemote.Close();
                    }
                }
        }

        #region "EventHandlers"
        public event EventHandler ProgressChange;
        public event EventHandler DownloadComplete;

        private void DownloadWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (this.ProgressChange != null)
                this.ProgressChange(this, new EventArgs());

            VideoDownloadProgess = e.ProgressPercentage;
        }
        private void DownloadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (this.DownloadComplete != null)
                this.DownloadComplete(this, new EventArgs());

            VideoDownloadProgess = 0;
        }
        #endregion
        #endregion
    }
}
